package handlers

import (
	"encoding/json"
	"strconv"

	"jianianhua-server/database"
	"jianianhua-server/models"
	"jianianhua-server/services"
	"jianianhua-server/utils"

	"github.com/gin-gonic/gin"
)

type AppointmentHandler struct {
	appointmentService *services.AppointmentService
}

func NewAppointmentHandler() *AppointmentHandler {
	return &AppointmentHandler{
		appointmentService: services.NewAppointmentService(),
	}
}

// CreateAppointmentConfig 创建预约配置
func (h *AppointmentHandler) CreateAppointmentConfig(c *gin.Context) {
	var req services.CreateAppointmentConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	config, err := h.appointmentService.CreateAppointmentConfig(&req)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, config)
}

// UpdateAppointmentConfig 更新预约配置
func (h *AppointmentHandler) UpdateAppointmentConfig(c *gin.Context) {
	date := c.Param("date")
	if date == "" {
		utils.BadRequestResponse(c, "日期参数不能为空")
		return
	}

	var req services.UpdateAppointmentConfigRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	config, err := h.appointmentService.UpdateAppointmentConfig(date, &req)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, config)
}

// GetAppointmentConfig 获取预约配置
func (h *AppointmentHandler) GetAppointmentConfig(c *gin.Context) {
	date := c.Param("date")
	if date == "" {
		utils.BadRequestResponse(c, "日期参数不能为空")
		return
	}

	config, err := h.appointmentService.GetAppointmentConfig(date)
	if err != nil {
		// 如果没有找到配置，返回默认配置
		defaultConfig := &models.AppointmentConfig{
			Date:            date,
			StartTime:       "09:30",
			EndTime:         "22:00",
			IntervalMinutes: 90,
			MaxAppointments: 0,
			Status:          1,
		}
		utils.SuccessResponse(c, defaultConfig)
		return
	}

	utils.SuccessResponse(c, config)
}

// CreateAppointment 创建预约
func (h *AppointmentHandler) CreateAppointment(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	// 检查用户是否被拉黑
	var user models.User
	err := database.DB.Where("id = ?", userID).First(&user).Error
	if err != nil {
		utils.InternalServerErrorResponse(c, "获取用户信息失败")
		return
	}

	if user.IsBlacklisted {
		utils.BadRequestResponse(c, "网络异常，请稍后再试")
		return
	}

	// 先获取用户设置，决定是否验证手机号
	var userSettings models.UserSettings
	if err := database.DB.First(&userSettings).Error; err != nil {
		// 如果获取设置失败，默认不验证手机号
		userSettings.PhoneHidden = true
	}

	var req services.CreateAppointmentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	// 根据用户设置验证手机号
	if !userSettings.PhoneHidden {
		if req.CustomerPhone == "" {
			utils.BadRequestResponse(c, "手机号不能为空")
			return
		}
	}

	appointment, err := h.appointmentService.CreateAppointment(userID, &req)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, appointment)
}

// GetAppointments 获取预约列表（返回所有数据，不分页）
func (h *AppointmentHandler) GetAppointments(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	date := c.Query("date")

	appointments, total, err := h.appointmentService.GetAppointments(userID, date)
	if err != nil {
		utils.InternalServerErrorResponse(c, "获取预约列表失败: "+err.Error())
		return
	}

	utils.SuccessResponse(c, gin.H{
		"list":      appointments,
		"total":     total,
		"page":      1,
		"page_size": len(appointments),
	})
}

// GetAppointmentDetail 获取预约详情
func (h *AppointmentHandler) GetAppointmentDetail(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	id := c.Param("id")
	if id == "" {
		utils.BadRequestResponse(c, "预约ID不能为空")
		return
	}

	// 将字符串ID转换为uint
	appointmentID, err := strconv.ParseUint(id, 10, 32)
	if err != nil {
		utils.BadRequestResponse(c, "无效的预约ID")
		return
	}

	// 查询预约记录
	var appointment models.Appointment
	err = database.DB.Where("id = ?", uint(appointmentID)).Preload("Config").Preload("User").First(&appointment).Error
	if err != nil {
		utils.BadRequestResponse(c, "预约记录不存在")
		return
	}

	// 检查权限：只有管理员或预约创建者可以查看详情
	// 通过查询用户信息检查是否为管理员
	var user models.User
	if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
		utils.InternalServerErrorResponse(c, "获取用户信息失败")
		return
	}
	isAdmin := user.Role == "admin"

	if !isAdmin && appointment.UserID != userID {
		utils.ForbiddenResponse(c, "无权限查看此预约")
		return
	}

	// 解析效果图数据
	var effectImages []string
	if appointment.EffectImages != "" {
		if err := json.Unmarshal([]byte(appointment.EffectImages), &effectImages); err != nil {
			// 解析失败时使用空数组
			effectImages = []string{}
		}
	}

	createdBy := ""
	if appointment.User != nil {
		createdBy = appointment.User.Nickname
	}

	response := services.AppointmentResponse{
		ID:              appointment.ID,
		AppointmentDate: appointment.AppointmentDate,
		AppointmentTime: appointment.AppointmentTime,
		EstimatedTime:   appointment.EstimatedTime,
		QueueNumber:     appointment.QueueNumber,
		Status:          appointment.Status,
		CustomerName:    appointment.CustomerName,
		CustomerPhone:   appointment.CustomerPhone,
		CustomerRemark:  appointment.CustomerRemark,
		ServiceID:       appointment.ServiceID,
		ProductTitle:    appointment.ProductTitle,
		EffectImages:    effectImages,
		CreatedBy:       createdBy,
	}

	utils.SuccessResponse(c, response)
}

// CancelAppointment 取消预约
func (h *AppointmentHandler) CancelAppointment(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	id := c.Param("id")
	if id == "" {
		utils.BadRequestResponse(c, "预约ID不能为空")
		return
	}

	// 解析请求参数（可选：取消原因）
	var req struct {
		CancelReason string `json:"cancel_reason"`
	}
	c.ShouldBindJSON(&req) // 不强制要求，如果没有提供则使用空字符串

	// 调用服务层更新预约状态为已取消（status = 4）
	appointment, err := h.appointmentService.UpdateAppointmentStatus(id, 4, userID, req.CancelReason)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, appointment)
}

// UpdateAppointmentStatus 更新预约状态
func (h *AppointmentHandler) UpdateAppointmentStatus(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	id := c.Param("id")
	if id == "" {
		utils.BadRequestResponse(c, "预约ID不能为空")
		return
	}

	// 解析请求参数
	var req struct {
		Status      int    `json:"status" binding:"required"`
		CancelReason string `json:"cancel_reason"` // 可选：取消原因
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	// 验证状态值
	if req.Status < 1 || req.Status > 4 {
		utils.BadRequestResponse(c, "状态值无效，必须是1-4之间的数字")
		return
	}

	// 调用服务层更新预约状态
	appointment, err := h.appointmentService.UpdateAppointmentStatus(id, req.Status, userID, req.CancelReason)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, appointment)
}

// UpdateAppointmentEstimatedTime 更新预约预计到店时间
func (h *AppointmentHandler) UpdateAppointmentEstimatedTime(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	id := c.Param("id")
	if id == "" {
		utils.BadRequestResponse(c, "预约ID不能为空")
		return
	}

	var req struct {
		EstimatedTime string `json:"estimated_time" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "请求参数错误: "+err.Error())
		return
	}

	// 调用服务层更新预计到店时间
	appointment, err := h.appointmentService.UpdateAppointmentEstimatedTime(id, req.EstimatedTime, userID)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, appointment)
}

// ToggleLeaveStatus 切换请假状态
func (h *AppointmentHandler) ToggleLeaveStatus(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	var req struct {
		Date        string `json:"date"`
		IsLeave     bool   `json:"is_leave"`
		LeaveReason string `json:"leave_reason"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	// 优先使用请求体中的日期，如果没有则使用URL参数
	date := req.Date
	if date == "" {
		date = c.Param("date")
	}

	if date == "" {
		utils.BadRequestResponse(c, "日期参数不能为空")
		return
	}

	// 调用服务层切换请假状态
	config, err := h.appointmentService.ToggleLeaveStatus(date, req.IsLeave, req.LeaveReason, userID)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, config)
}

// GetLeaveStatus 获取请假状态
func (h *AppointmentHandler) GetLeaveStatus(c *gin.Context) {
	date := c.Param("date")
	if date == "" {
		utils.BadRequestResponse(c, "日期参数不能为空")
		return
	}

	// 调用服务层获取请假状态
	config, err := h.appointmentService.GetAppointmentConfigByDate(date)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	// 只返回请假相关信息
	leaveInfo := map[string]interface{}{
		"date":         config.Date,
		"is_leave":     config.IsLeave,
		"leave_reason": config.LeaveReason,
	}

	utils.SuccessResponse(c, leaveInfo)
}

// GetAvailableDates 获取所有可用的预约日期
func (h *AppointmentHandler) GetAvailableDates(c *gin.Context) {
	dates, err := h.appointmentService.GetAvailableDates()
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, gin.H{
		"dates": dates,
	})
}

// GetBookedTimeSlots 获取已预约的时间段
func (h *AppointmentHandler) GetBookedTimeSlots(c *gin.Context) {
	date := c.Param("date")
	if date == "" {
		utils.BadRequestResponse(c, "日期参数不能为空")
		return
	}

	// 调用服务层获取已预约的时间段
	bookedSlots, err := h.appointmentService.GetBookedTimeSlots(date)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, map[string]interface{}{
		"date":          date,
		"booked_counts": bookedSlots.BookedCounts,
		"staff_count":   bookedSlots.StaffCount,
	})
}

// CancelAppointmentsByDate 取消指定日期的所有预约
func (h *AppointmentHandler) CancelAppointmentsByDate(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	// 解析请求参数
	var req struct {
		Date   string `json:"date" binding:"required"`
		Reason string `json:"reason" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	// 调用服务层取消指定日期的所有预约
	result, err := h.appointmentService.CancelAppointmentsByDate(req.Date, req.Reason, userID)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, result)
}


// SetGlobalStaffCount 设置全局美甲师人数
func (h *AppointmentHandler) SetGlobalStaffCount(c *gin.Context) {
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		utils.UnauthorizedResponse(c, "用户未登录")
		return
	}

	var req struct {
		StaffCount int `json:"staff_count" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequestResponse(c, "参数错误: "+err.Error())
		return
	}

	err := h.appointmentService.SetGlobalStaffCount(req.StaffCount, userID)
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, gin.H{
		"message":     "美甲师人数设置成功",
		"staff_count": req.StaffCount,
	})
}

// GetGlobalStaffCount 获取全局美甲师人数
func (h *AppointmentHandler) GetGlobalStaffCount(c *gin.Context) {
	staffCount, err := h.appointmentService.GetGlobalStaffCount()
	if err != nil {
		utils.BadRequestResponse(c, err.Error())
		return
	}

	utils.SuccessResponse(c, gin.H{
		"staff_count": staffCount,
	})
}
